<template>
  <g
    v-if="isSvg"
    ref="elm"
    :style="{touchAction: 'none!important', transform: `translate(${posX + x}px,${posY + y}px)`}"
    @mousedown="onDragStart"
    @mouseup="onDragEnd"
  >
    <slot></slot>
  </g>
  <div
    v-else
    ref="elm"
    :style="{touchAction: 'none!important', transform: `translate(${posX + x}px,${posY + y}px)`}"
    @mousedown="onDragStart"
    @mouseup="onDragEnd"
  >
    <slot></slot>
  </div>
</template>

<script>
export default {
  data () {
    return {
      /** 鼠标点击元素的原始位置，单位是px */
      originX: 0,
      originY: 0,

      /** 已经移动的位移，单位是px */
      lastX: 0,
      lastY: 0,

      // 元素的位置
      posX: 0,
      posY: 0,

      // 是否移动了
      isMove: false
    };
  },
  props: {
    /**
     * 给予元素一个x,y的初始位置，单位是px
     */
    x: {
      type: Number,
      default: 0
    },
    y: {
      type: Number,
      default: 0
    },
    /**
     * 内部的移动拖拽把手
     * 拖拽把手className一定要设置成handle并且这个属性设置成true
     */
    hasDraggerHandle: {
      type: Boolean,
      default: false
    },
    isStill: {
      type: Boolean,
      default: false
    },
    /**
     * 内部取消的区域
     */
    hasCancelHandle: {
      type: Boolean,
      default: false
    },
    isSvg: {
      type: Boolean,
      default: false
    },
    fullScreen: {
      type: Boolean,
      default: false
    },
    bounds: {
      type: Object
    },
    scrollX: {
      type: Number,
      default: 0
    },
    scrollY: {
      type: Number,
      default: 0
    },
    scale: {
      type: Number,
      default: 0
    }
  },
  methods: {
    // 开始拖拽
    onDragStart (event) {
      if (this.isStill) return false;
      this.isMove = false;
      document.body.style.userSelect = 'none';

      if (this.hasDraggerHandle) {
        if (event.target.className !== 'handle') return;
      }

      if (this.hasCancelHandle) {
        if (event.target.className.split(' ').indexOf('cancel') > -1) return;
      }

      document.addEventListener('mousemove', this.move);
      document.addEventListener('mouseup', this.onDragEnd);

      if (
        this.bounds === 'parent' &&
        (typeof this.parent === 'undefined' || this.parent === null)
      ) {
        this.parent = event.currentTarget.offsetParent;
        this.self = event.currentTarget;
      }

      this.originX = event.pageX;
      this.originY = event.pageY;
    },

    // 移动的距离
    move (e) {
      let deltaX = (e.pageX - this.originX) / this.scale;
      let deltaY = (e.pageY - this.originY) / this.scale;
      const bounds = this.bounds;
      // 保证不超出右边界和底部
      if (bounds) {
        let currentX = this.x + deltaX;
        let currentY = this.y + deltaY;
        // 左
        if (currentX < bounds.left / this.scale) {
          deltaX = bounds.left / this.scale - this.x;
        }

        // 顶
        if (currentY < bounds.top / this.scale) {
          deltaY = bounds.top / this.scale - this.y;
        }

        // 右
        if (this.fullScreen) {
          if (currentX > bounds.right / this.scale - 50) {
            deltaX = bounds.right / this.scale - this.x - 50;
          }
        } else {
          if (currentX > bounds.right / this.scale - 180) {
            deltaX = bounds.right / this.scale - this.x - 180;
          }
        }

        // 底
        if (currentY > bounds.bottom / this.scale - 90) {
          deltaY = bounds.bottom / this.scale - this.y - 90;
        }
      }

      this.posX = deltaX;
      this.posY = deltaY;

      let moveX = this.x + this.posX
      let moveY = this.y + this.posY
      if (this.posX !== 0) {
        this.isMove = true
      }

      this.$emit('move', {
        e: e,
        x: moveX,
        y: moveY
      });

      this.originX = e.pageX;
      this.originY = e.pageY;
      this.posX = 0;
      this.posY = 0;
    },

    // 拖拽结束
    onDragEnd (event) {
      document.body.style.userSelect = '';
      document.removeEventListener('mousemove', this.move);
      document.removeEventListener('mouseup', this.onDragEnd);
      if (this.isMove) {
        this.$emit('dragEnd');
      }
    }
  }
};
</script>
